Solving 10385 - Duathlon (Ternary search)
[andmenj-acm.git] / 209 - Triangular vertices / Problem209.dpr
blob21ab427203aff5f8b68ee870a238b503876de983
1 program problem209 (input, output);\r
2 \r
3 {$APPTYPE CONSOLE}\r
4 \r
5 type\r
6  TPunto = Record\r
7   Num, Fila,\r
8   PosIzq, //La posición del punto contando desde el primer elemento de la izquierda de la fila\r
9   PosDcha //Lo mismo pero empezando por la derecha\r
10    : Integer;\r
11   end;\r
13 var\r
14   i, j, Distancia1 : integer;\r
15   Entrada : String;\r
16   Puntos : Array[0..5] of TPunto; //los puntos en el orden en que entran\r
17   PuntosOrdenados : Array[0..5] of TPunto; //los puntos ordenados de mayor a menor\r
18   Cuenta : Integer; //Cuenta el numero de puntos que le entraron - 1 (Porque el arreglo empieza en 0)\r
19   TempPt : TPunto; //Pt temporal usado para organizarlos de mayor a menor\r
21   PtsCorrectos : Set of Byte;\r
23 Function StrToInt(Const S: String): Integer;\r
24 Var\r
25   E: Integer;\r
26 Begin\r
27   Val(S, Result, E);\r
28 End;\r
30 procedure PrintIncorrectos();\r
31 var i : byte;\r
32 begin\r
33 for i := 0 to Cuenta do\r
34   Write(Puntos[i].Num, ' ');\r
35 WriteLn('are not the vertices of an acceptable figure');\r
36 end;\r
38 procedure PrintCorrecto(Figura : String);\r
39 var i : byte;\r
40 begin\r
41 for i := 0 to Cuenta do\r
42   Write(Puntos[i].Num, ' ');\r
43 WriteLn('are the vertices of a '+Figura);\r
44 end;\r
46 function GetFila(Numero : Integer) : Integer;\r
47 //retorna la fila de un numero o punto\r
48 var\r
49  Fila, Acum : Integer;\r
50 begin\r
51 Fila := 1;\r
52 Acum := 0;\r
53 repeat\r
54  Acum := Acum + Fila;\r
55  If Acum < Numero then\r
56   Fila := Fila + 1;\r
57 until Acum >= Numero;\r
58 Result := Fila; //Return\r
59 end;\r
61 function GetSumaDeFilas(Cuantas : Integer) : Integer;\r
62 //retorna la suma de todas las filas hasta Cuantas\r
63 var\r
64  i : integer;\r
65 begin\r
66 Result := 0;\r
67 For i := 1 to Cuantas do\r
68  Result := Result + i;\r
69 end;\r
71 function GetPosIzq(Numero, Fila : Integer) : Integer;\r
72 //retorna la posición izquierda respecto a la fila\r
73 begin\r
74 Result := Numero - (GetSumaDeFilas(Fila)-Fila);\r
75 end;\r
77 function GetPosDcha(Numero, Fila : Integer) : Integer;\r
78 //retorna la posición derecha respecto a la fila\r
79 begin\r
80 Result := GetSumaDeFilas(Fila) - Numero + 1;\r
81 end;\r
83 //Empieza!\r
87 begin\r
88 PtsCorrectos := [3, 4, 6];\r
90   while not eof(input) do\r
91   begin\r
92     FillChar(Puntos, SizeOf(Puntos), 0); //Limpia el arreglo y lo llena todo con 0's\r
93     Cuenta := -1;\r
94     ReadLn(Entrada);\r
95     If Length(Entrada) = 0 then Break; //si no introducen ningun caracter entonces salir\r
96     If Entrada[Length(Entrada)] <> ' ' then Entrada := Entrada + ' '; //Agrega un espacio al final para poder "parsear" todos los numeros\r
97     While Pos(' ', Entrada) > 0 do\r
98       begin\r
99       Cuenta := Cuenta + 1;\r
100       Puntos[Cuenta].Num := StrToInt(Copy(Entrada, 1, Pos(' ', Entrada)-1));\r
101       Delete(Entrada, 1, Pos(' ', Entrada));\r
102       end;\r
103    //Aquí ya he leído todos los puntos y están en el arreglo Puntos. La variable Cuenta contiene el numero de elementos que hay\r
105     if not ((Cuenta+1) in PtsCorrectos) then //No son 3, 4 o 6 pts, entonces es incorrecto\r
106      begin\r
107      PrintIncorrectos();\r
108      Continue; //Salta al pròximo while\r
109      end;\r
111      for i := 0 to Cuenta do\r
112       begin\r
113       Puntos[i].Fila := GetFila(Puntos[i].Num);\r
114       Puntos[i].PosIzq := GetPosIzq(Puntos[i].Num, Puntos[i].Fila);      \r
115       Puntos[i].PosDcha := GetPosDcha(Puntos[i].Num, Puntos[i].Fila);\r
116       end;\r
118       FillChar(PuntosOrdenados, SizeOf(PuntosOrdenados), 0);\r
119       //Organizarlos de mayor a menor\r
121       for i := 0 to Cuenta do\r
122        PuntosOrdenados[i] := Puntos[i]; //copia el arreglo\r
124       for i := 0 to Cuenta do\r
125       begin\r
126        for j := Cuenta downto i+1 do\r
127        begin\r
128        if PuntosOrdenados[j].Num < PuntosOrdenados[j-1].Num then\r
129         begin\r
130         TempPt := PuntosOrdenados[j];\r
131         PuntosOrdenados[j] := PuntosOrdenados[j-1];\r
132         PuntosOrdenados[j-1] := TempPt;\r
133         end;\r
134        end;\r
135       end;\r
136       //Aqui se encuentran todos los puntos organizados de mayor a menor en el arreglo PuntosOrdenados\r
138    case (Cuenta+1) of\r
140 /////////////////////////////////////////////\r
141 ////////////// Triangulo ////////////////////\r
142 /////////////////////////////////////////////\r
143          //                         _\r
144      3: //Triangulo : Hay 2 Tipos: \/  y /_\\r
145        begin\r
146        if PuntosOrdenados[0].Fila = PuntosOrdenados[1].Fila then //Tipo 1: Los dos primeros puntos estan en la misma fila\r
147         begin\r
148         Distancia1 := PuntosOrdenados[0].PosDcha - PuntosOrdenados[1].PosDcha;\r
149         if (PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)\r
150            and (PuntosOrdenados[2].PosIzq = PuntosOrdenados[1].PosIzq)\r
151            and ((PuntosOrdenados[2].Fila - PuntosOrdenados[0].Fila) = Distancia1) then\r
152            begin\r
153            PrintCorrecto('triangle');\r
154            Continue;\r
155            end\r
156         else\r
157            begin\r
158            PrintIncorrectos();\r
159            Continue;\r
160            end;\r
161         end\r
162        else if PuntosOrdenados[1].Fila = PuntosOrdenados[2].Fila then //Tipo 2: El 2do y 3er punto estan en la misma fila\r
163         begin\r
164         Distancia1 := PuntosOrdenados[1].PosDcha - PuntosOrdenados[2].PosDcha;\r
165         if (PuntosOrdenados[1].PosIzq = PuntosOrdenados[0].PosIzq)\r
166            and (PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)\r
167            and ((PuntosOrdenados[2].Fila - PuntosOrdenados[0].Fila)=Distancia1) then\r
168            begin\r
169            PrintCorrecto('triangle');\r
170            Continue;\r
171            end\r
172         else\r
173            begin\r
174            PrintIncorrectos();\r
175            Continue;\r
176            end;\r
177         end\r
178        else  //No hay 2 puntos en la misma fila\r
179         begin\r
180         PrintIncorrectos();\r
181         Continue;\r
182         end;\r
183        end;\r
185 /////////////////////////////////////////////\r
186 ////////////// Paralelogramo ////////////////\r
187 /////////////////////////////////////////////\r
189      4:\r
190      begin                                                        //       _    _\r
191        if PuntosOrdenados[0].Fila = PuntosOrdenados[1].Fila then // tipo /_/ o \_\\r
192         begin\r
193         Distancia1 := PuntosOrdenados[0].PosDcha - PuntosOrdenados[1].PosDcha;\r
194         if ((PuntosOrdenados[2].PosIzq = PuntosOrdenados[0].PosIzq)\r
195             and (PuntosOrdenados[3].PosIzq = PuntosOrdenados[1].PosIzq)\r
196             and ((PuntosOrdenados[2].Fila-PuntosOrdenados[0].Fila)=Distancia1))\r
197            or\r
198            ((PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)\r
199             and (PuntosOrdenados[3].PosDcha = PuntosOrdenados[1].PosDcha)\r
200             and ((PuntosOrdenados[2].Fila-PuntosOrdenados[0].Fila)=Distancia1)) then\r
201            begin\r
202            PrintCorrecto('parallelogram');\r
203            Continue;\r
204            end\r
205         else\r
206           begin\r
207           PrintIncorrectos();\r
208           Continue;\r
209           end;\r
210         end                                                              //      /\\r
211        else if PuntosOrdenados[1].Fila = PuntosOrdenados[2].Fila then   //  tipo \/\r
212         begin\r
213         Distancia1 := PuntosOrdenados[1].Fila - PuntosOrdenados[0].Fila;\r
214         if (PuntosOrdenados[1].PosIzq = PuntosOrdenados[0].PosIzq)\r
215            and (PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)\r
216            and ((PuntosOrdenados[3].Fila-PuntosOrdenados[1].Fila)=Distancia1)\r
217            and (PuntosOrdenados[3].PosDcha = PuntosOrdenados[1].PosDcha)\r
218            and (PuntosOrdenados[3].PosIzq = PuntosOrdenados[2].PosIzq) then\r
219          begin\r
220          PrintCorrecto('parallelogram');\r
221          Continue;\r
222          end\r
223         else\r
224           begin\r
225           PrintIncorrectos();\r
226           Continue;\r
227           end;\r
228         end\r
229        else\r
230         begin\r
231         PrintIncorrectos();\r
232         Continue;\r
233         end;\r
234        end;\r
237 /////////////////////////////////////////////\r
238 /////////////// Hexagono ////////////////////\r
239 /////////////////////////////////////////////              ___\r
240                                                   //      /   \\r
241      6:                                          //      |    |\r
242        begin //Solo hay un tipo posible         //       \___/\r
243        Distancia1 := PuntosOrdenados[0].PosDcha - PuntosOrdenados[1].PosDcha;\r
244        if (PuntosOrdenados[0].Fila = PuntosOrdenados[1].Fila)\r
245           and (PuntosOrdenados[2].PosIzq = PuntosOrdenados[0].PosIzq)\r
246           and (PuntosOrdenados[3].PosDcha = PuntosOrdenados[1].PosDcha)\r
247           and (PuntosOrdenados[2].Fila - PuntosOrdenados[0].Fila = Distancia1)\r
248           and (PuntosOrdenados[4].PosDcha = PuntosOrdenados[2].PosDcha)\r
249           and (PuntosOrdenados[5].PosIzq = PuntosOrdenados[3].PosIzq)\r
250           and (PuntosOrdenados[4].Fila - PuntosOrdenados[2].Fila = Distancia1) then\r
251         begin\r
252         PrintCorrecto('hexagon');\r
253         Continue;\r
254         end\r
255       else\r
256         begin\r
257         PrintIncorrectos();\r
258         Continue;\r
259         end;\r
260        end;\r
261    end;//case   \r
263   end;\r
264 end.\r